package xin.codedream.codelog.service.impl;

import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xin.codedream.codelog.dao.ArticleTagDao;
import xin.codedream.codelog.model.entity.ArticleTag;
import xin.codedream.codelog.model.entity.Tag;
import xin.codedream.codelog.service.ArticleTagsService;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 文章标签功能服务实现
 *
 * @author NGLSL
 * @date 2018/8/19
 */
@Log4j2
@Service
public class ArticleTagsServiceImpl implements ArticleTagsService {
    @Resource
    private ArticleTagDao articleTagsDao;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveArticleTags(List<ArticleTag> articleTags) {
        AtomicBoolean result = new AtomicBoolean(false);
        articleTags.forEach(articleTag -> articleTag.getTags().forEach(tag ->{
            articleTag.setTag(tag);
            result.set(articleTagsDao.insertArticleTags(articleTag) > 0);
        }));
        return result.get();
    }

    @Override
    public List<ArticleTag> findArticleTagsByArticleId(Long articleId) {
        return articleTagsDao.listArticleTagsByArticleId(articleId);
    }

    @Override
    public boolean removeArticleTagByArticleId(Long articleId, Set<Long> tags) {
        return articleTagsDao.deleteArticleTagByArticleId(articleId, tags) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateArticleTag(ArticleTag articleTags) {
        List<ArticleTag> articleTagList = this.findArticleTagsByArticleId(articleTags.getArticle().getArticleId());
        List<Tag> tags = new ArrayList<>();
        articleTagList.forEach(articleTag -> tags.add(articleTag.getTag()));
        Map<Long, Long> tagMap = new HashMap<>(16);
        Long articleId = articleTags.getArticle().getArticleId();
        // 遍历查询该标签是否还存在，存在的添加进Map里面
        articleTags.getTags().forEach(aTag -> {
            if (tags.contains(aTag)) {
                tagMap.put(aTag.getTagId(), articleId);
            }
        });
        // 移除所有与该文章关联的标签
        if (tagMap.isEmpty()) {
            this.removeArticleTagByArticleId(articleId, null);
        } else {
            // 移除除了存在关联的标签
            this.removeArticleTagByArticleId(articleId, tagMap.keySet());
        }
        // 保存新标签
        List<ArticleTag> tagList = new ArrayList<>();
        articleTags.getTags().stream()
                .filter(tag -> !tagMap.containsKey(tag.getTagId()))
                .forEach(tag -> tagList.add(new ArticleTag(articleTags.getArticle(), tag)));
        return tagList.isEmpty() || this.saveArticleTags(tagList);
    }
}
